<template>
  <el-row>
    <div class="block">
      <el-date-picker v-model="value2" type="datetimerange" :shortcuts="shortcuts" range-separator="To" start-placeholder="起始日期" end-placeholder="结束日期" />
    </div>
    <div class="block">
      <el-select v-model="value3" placeholder="选择区域" style="width: 240px">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
      </el-select>
    </div>
    <div class="block">
      <el-button @click="toggleChartType">{{ buttonLabel }}</el-button>
    </div>
  </el-row>
  <div>
    <el-card><div ref="chart" style="height: 300px; width: 1300px"></div></el-card>
    <el-card><div ref="chart3" style="height: 300px; width: 1300px"></div></el-card>
    <el-card><div ref="chart2" style="height: 300px; width: 1300px"></div></el-card>
  </div>
  <el-card>
    <el-table :data="pagedTableData1" border style="width: 90%">
  <el-table-column prop="timestamp" label="时间" width="190" :formatter="formatTime.formatTime"></el-table-column>
  <el-table-column prop="assetnum" label="工位" width="170"></el-table-column>
  <el-table-column prop="location" label="区域" width="60"></el-table-column>
  <el-table-column prop="level" label="等级" width="60"></el-table-column>
  <el-table-column prop="name" label="信号" width="130"></el-table-column>
  <el-table-column prop="description" label="详细描述" width="420"></el-table-column>
  <el-table-column prop="duration" label="停机时间(min)" width="140"></el-table-column>
</el-table>
    <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[5, 10, 30, 50]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="totalItems"
      />
  </el-card>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, toRef, computed} from "vue";
import * as echarts from "echarts"; 
import axios from "axios";

const value2 = ref([]);
const value3 = ref("CBM1");
const options = [
  { value: "CBM1", label: "缸体M1" },
  { value: "CBM2", label: "缸体M2" },
  { value: "CHM1", label: "缸盖M1" },
  { value: "CHM2", label: "缸盖M2" },
  { value: "CS", label: "曲轴" },
  { value: "AS", label: "装配" },
];

const chart = ref(); 
const chart2 = ref();
const chart3 = ref();
const chartType = ref('data'); 
const buttonLabel = ref('按工位排序'); 

const series_data1 = ref([]);
const series_data2 = ref([]);
const series_data3 = ref([]);
const tableData = ref([]);
const currentPage = ref(1);
const pageSize = ref(5);
const totalItems = ref(0);

const toggleChartType = () => {
  if (chartType.value === 'assetnum') {
    chartType.value = 'data';
    buttonLabel.value = '按工位排序';
  } else {
    chartType.value = 'assetnum';
    buttonLabel.value = '按停机频次排序';
  }

  if (chartType.value === 'data') {
    series_data3.value.sort((a, b) => b.value - a.value);
  } else {
    series_data3.value.sort((a, b) => a.name.localeCompare(b.name));
  }

  use_show_data_in_html2();
};

const handleSizeChange = (val: number) => {
  pageSize.value = val;
  updatePagedData();
};
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  updatePagedData();
};
const updatePagedData = () => {
  const startIndex = (currentPage.value - 1) * pageSize.value;
  const endIndex = startIndex + pageSize.value;
  pagedTableData1.value = tableData.value.slice(startIndex, endIndex);
};

const pagedTableData1 = ref([]);

const formatTime = computed(() => ({
  formatTime(row, column) {
    if (column.property === 'timestamp') {
      return row[column.property].split('.')[0];
    }
    return row[column.property];
  }
}));

const formatDate = (d: string) => {
  const date = new Date(d);
  const YY = date.getFullYear() + "-";
  const MM = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
  const DD = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
  const hh = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
  const mm = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":";
  const ss = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
  return YY + MM + DD + " " + hh + mm + ss;
};

let construct_url = "";

watch([toRef(value2), toRef(value3)], ([newDateRange, newValue3]) => {
  const start_time = formatDate(newDateRange[0]);
  const end_time = formatDate(newDateRange[1]);
  construct_url = "http://10.64.35.32:8000/postgresql_data_api/get_DataFaultcode_data/?" + "start_time=" + start_time?.toString() + "&end_time=" + end_time?.toString() + "&assetnum=" + newValue3 + "&page_size=" + 100001;
  use_show_data_in_html2();
});

const use_show_data_in_html2 = async () => {
  console.log(construct_url);
  const response = await axios.get(construct_url);
  const data = response.data;
  console.log(data);

  const start_time = formatDate(value2.value[0]);
  const end_time = formatDate(value2.value[1]);

  const machineFaultUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataMachinefault_data/?assetnum=${value3.value}&start_time=${start_time}&end_time=${end_time}&page_size=100001`;
  const machineFaultResponse = await axios.get(machineFaultUrl);
  const machineFaultData = machineFaultResponse.data;
  const filteredMachineFaultData = machineFaultData.filter(item => item.duration <= 600);
  series_data1.value = [];
  series_data2.value = [];
  series_data3.value = [];

  const countMap = new Map();
  const stopCountMap = new Map();
  const stopTimeMap = new Map();

  data.forEach(item => {
    const key = item.assetnum;
    if (item.fault_id === 0) {
      if (!stopCountMap.has(key)) {
        stopCountMap.set(key, 0);
      }
      stopCountMap.set(key, stopCountMap.get(key) + 1);
    } else {
      const machineFaultItem = filteredMachineFaultData.find(machineFaultItem => machineFaultItem.faulttime === item.timestamp);
      if (!machineFaultItem) return;

      if (!countMap.has(key)) {
        countMap.set(key, 0);
      }
      countMap.set(key, countMap.get(key) + 1);

      if (machineFaultItem.duration !== null) {
        if (!stopTimeMap.has(key)) {
          stopTimeMap.set(key, 0);
        }
        stopTimeMap.set(key, stopTimeMap.get(key) + machineFaultItem.duration);
      }
    }
  });

  let sortedEntries = [];

  if (chartType.value === 'assetnum') {
    const nonOpEntries = Array.from(countMap.entries()).filter(([key]) => !/OP\d+/.test(key));
    const opEntries = Array.from(countMap.entries()).filter(([key]) => /OP\d+/.test(key));

    const sortedOpEntries = opEntries.sort((a, b) => {
      const aMatch = a[0].match(/OP(\d+)(\D*)/);
      const bMatch = b[0].match(/OP(\d+)(\D*)/);

      const aNum = parseInt(aMatch[1], 10);
      const bNum = parseInt(bMatch[1], 10);

      if (aNum !== bNum) {
        return aNum - bNum;
      }
    
      return aMatch[2].localeCompare(bMatch[2]);
    });

    sortedEntries = [...nonOpEntries, ...sortedOpEntries];
  } else if (chartType.value === 'data') {
    sortedEntries = Array.from(countMap.entries()).sort((a, b) => b[1] - a[1]);
  }

  series_data1.value = sortedEntries.map(entry => entry[0]);
  series_data2.value = sortedEntries.map(entry => entry[1]);

  const stopSeriesData = sortedEntries.map(entry => stopCountMap.get(entry[0]) || 0);
  series_data3.value = series_data1.value.map(assetnum => ({
    name: assetnum,
    value: stopTimeMap.get(assetnum) || 0,
    stopCount: countMap.get(assetnum) || 0,
  }));
  console.log('series_data1.value',series_data1.value)
  console.log('series_data2.value',series_data2.value)
  console.log('series_data3.value',series_data3.value)
  if (chartType.value === 'data') {
    series_data3.value.sort((a, b) => b.value - a.value);
  } else {
    series_data3.value.sort((a, b) => a.name.localeCompare(b.name));
  }

  initChart(series_data2.value, stopSeriesData);
  initChart3();
};

const useShowDataInHtmlForTable = async (point_id: string) => {
  const start_time = formatDate(value2.value[0]);
  const end_time = formatDate(value2.value[1]);
  let faultCodeUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataFaultcode_data/?start_time=${start_time}&end_time=${end_time}&assetnum=${point_id}&page_size=100001`;
  console.log('url1', faultCodeUrl);
  const faultCodeResponse = await axios.get(faultCodeUrl);
  let data = faultCodeResponse.data;
  data = data.filter(item => item.fault_id !== 0);

  let machineFaultUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataMachinefault_data/?assetnum=${point_id}&start_time=${start_time}&end_time=${end_time}&page_size=10000`;
  console.log('url2', machineFaultUrl);
  const machineFaultResponse = await axios.get(machineFaultUrl);
  let machineFaultData = machineFaultResponse.data;
  const filteredMachineFaultData = machineFaultData.filter(item => item.duration <= 600);
  const faultTimes = new Set(filteredMachineFaultData.map(item => item.faulttime));
  console.log('faultTimes',faultTimes)
  const countMap = new Map();
  const stopDurationMap = new Map();

  data.forEach(item => {
    if (faultTimes.has(item.timestamp)) { 
      const date = new Date(item.timestamp);
      const month = date.getMonth() + 1;
      const day = date.getDate();
      const hour = date.getHours();
      const formattedHour = `${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day} ${hour < 10 ? '0' + hour : hour}:00-${(hour + 1) % 24 < 10 ? '0' + (hour + 1) % 24 : (hour + 1) % 24}:00`;

      if (!countMap.has(formattedHour)) {
        countMap.set(formattedHour, 0);
      }
      countMap.set(formattedHour, countMap.get(formattedHour) + 1);

      const machineFaultItem = filteredMachineFaultData.find(machineFaultItem => machineFaultItem.faulttime === item.timestamp);
      if (machineFaultItem && machineFaultItem.duration !== null) {
        if (!stopDurationMap.has(formattedHour)) {
          stopDurationMap.set(formattedHour, 0);
        }
        stopDurationMap.set(formattedHour, stopDurationMap.get(formattedHour) + machineFaultItem.duration);
      }
    }
  });

  console.log('countMap',countMap)
  console.log('stopDurationMap', stopDurationMap); 

  series_data1.value = Array.from(countMap.keys());
  series_data2.value = Array.from(countMap.values());
  series_data3.value = Array.from(stopDurationMap.values()); 
  console.log('series_data2.value',series_data2.value)
  console.log('series_data3.value', series_data3.value);

  useShowDataTableData(point_id, data);

  initChart2(point_id);
};

const useShowDataTableData = async (point_id: string, data: any[]) => {
  let faultContentData = [];
  
  try {
    const newUrl = `http://10.64.35.32:8000/ephm_pgsql_api/faultcontent_api/?assetnum=${point_id}`;
    const response = await axios.get(newUrl);
    faultContentData = response.data;
  } catch (error) {
    console.error('Failed to fetch fault content data:', error);
  }

  const start_time = formatDate(value2.value[0]);
  const end_time = formatDate(value2.value[1]);

  let machineFaultData = [];
  let filteredMachineFaultData = [];
  try {
    const machineFaultUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataMachinefault_data/?assetnum=${point_id}&start_time=${start_time}&end_time=${end_time}&page_size=10000`;
    const machineFaultResponse = await axios.get(machineFaultUrl);
    machineFaultData = machineFaultResponse.data;
    filteredMachineFaultData = machineFaultData.filter(item => item.duration <= 600);
  } catch (error) {
    console.error('Failed to fetch machine fault data:', error);
  }
  const matchedData = data.filter(item => {
    if (item.fault_id === 0) return false;

    const machineFaultItem = filteredMachineFaultData.find(machineFaultItem => machineFaultItem.faulttime === item.timestamp);
    if (!machineFaultItem) return false;

    return true;
  }).map(item => {
    const machineFaultItem = filteredMachineFaultData.find(machineFaultItem => machineFaultItem.faulttime === item.timestamp);
    const faultItem = faultContentData.length > 0 ? faultContentData.find(faultItem => faultItem.code === item.data.toString()) : null;

    return {
      timestamp: item.timestamp,
      assetnum: item.assetnum,
      location: faultItem ? faultItem.location : null,
      level: faultItem ? faultItem.level : null,
      name: faultItem ? faultItem.name : null,
      description: faultItem ? faultItem.description : null,
      duration: machineFaultItem ? machineFaultItem.duration : null
    };
  });

  tableData.value = matchedData;
  totalItems.value = tableData.value.length;
  updatePagedData();
  console.log('table', tableData.value);
};

const useShowDataTableData2 = async (point_id: string, start_time: string, end_time: string) => {
  let data = [];
  try {
    const newUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataFaultcode_data/?start_time=${start_time}&end_time=${end_time}&assetnum=${point_id}&page_size=100001`;
    const response = await axios.get(newUrl);
    data = response.data.filter(item => item.fault_id !== 0);
  } catch (error) {
    console.error('Failed to fetch data fault code data:', error);
  }
  
  let faultContentData = [];
  try {
    const faultContentUrl = `http://10.64.35.32:8000/ephm_pgsql_api/faultcontent_api/?assetnum=${point_id}`;
    const faultContentResponse = await axios.get(faultContentUrl);
    faultContentData = faultContentResponse.data;
  } catch (error) {
    console.error('Failed to fetch fault content data:', error);
  }

  let machineFaultData = [];
  let filteredMachineFaultData = [];
  try {
    const machineFaultUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataMachinefault_data/?assetnum=${point_id}&start_time=${start_time}&end_time=${end_time}&page_size=10000`;
    const machineFaultResponse = await axios.get(machineFaultUrl);
    machineFaultData = machineFaultResponse.data;
    filteredMachineFaultData = machineFaultData.filter(item => item.duration <= 600);
  } catch (error) {
    console.error('Failed to fetch machine fault data:', error);
  }
  console.log('machineFaultData',machineFaultData)
  const matchedData = data.filter(item => {
    if (item.fault_id === 0) return false;

    const machineFaultItem = filteredMachineFaultData.find(machineFaultItem => machineFaultItem.faulttime === item.timestamp);
    if (!machineFaultItem) return false;

    return true;
  }).map(item => {
    const machineFaultItem = filteredMachineFaultData.find(machineFaultItem => machineFaultItem.faulttime === item.timestamp);
    const faultItem = faultContentData.length > 0 ? faultContentData.find(faultItem => faultItem.code === item.data.toString()) : null;

    return {
      timestamp: item.timestamp,
      assetnum: item.assetnum,
      location: faultItem ? faultItem.location : null,
      level: faultItem ? faultItem.level : null,
      name: faultItem ? faultItem.name : null,
      description: faultItem ? faultItem.description : null,
      duration: machineFaultItem ? machineFaultItem.duration : null
    };
  });

  tableData.value = matchedData;
  totalItems.value = tableData.value.length;
  updatePagedData();
  console.log('table', tableData.value);
};

const initChart = async (nonStopData, stopData) => {
  if (chart.value == null) {
    return;
  }

  echarts.dispose(chart.value);
  const myChart = echarts.init(chart.value);

  let option = {
    title: {
      text: `${value3.value}故障频次总况`,
      left: "center",
      textStyle: {
        color: "black",
      },
      subtextStyle: {
        fontWeight: "bold",
      },
    },
    tooltip: {
      trigger: "axis",
      formatter: function (params) {
        let result = params[0].name + "<br/>";
        params.forEach(param => {
          result += `${param.seriesName}: ${param.value}<br/>`;
        });
        return result;
      },
    },
    legend: {
      data: ["停机故障" , "非停机故障"],
      orient: "horizontal", 
      left: "left", 
      top: "top",
      itemGap: 10,
    },
    xAxis: {
      type: "category",
      data: series_data1.value,
      axisLabel: {
        rotate: 45,
      },
    },
    yAxis: {
      splitLine:{show: false},
      type: "value",
      name: '故障次数',
    },
    series: [
      {
        name: '停机故障',
        data: nonStopData,
        type: "bar",
        stack: 'total',
        color: "#D84A62",
        label: {
          show: true,
          position: 'top',
          formatter: function (param) {
            return param.value;
          },
        },
      },
      {
        name: '非停机故障',
        data: stopData,
        type: "bar",
        stack: 'total',
        color: "#59c4e6",
        label: {
          show: true,
          position: 'top',
          formatter: function (param) {
            return param.value;
          },
        },
      },
    ],
  };

  myChart.on('click', (params) => {
    console.log('Clicked:', params);
    const point_id = params.name;
    useShowDataInHtmlForTable(point_id);
  });

  myChart.setOption(option);
};

const initChart2 = async (point_id: string) => {
  if (chart2.value == null) {
    return;
  }

  echarts.dispose(chart2.value);
  const myChart = echarts.init(chart2.value);

  const faultCountData = series_data2.value;
  console.log('1',faultCountData)
  const stopDurationData = series_data3.value;

  let option = {
    title: {
      text: `${point_id} 小时故障统计`,
      left: "center",
      textStyle: {
        color: "black",
      },
      subtextStyle: {
        fontWeight: "bold",
      },
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
      },
      formatter: function (params) {
        let result = `${params[0].name}<br>`;
        params.forEach(param => {
          if (param.seriesName === '停机次数') {
            result += `${param.marker} ${param.seriesName}: ${param.value}<br>`;
          } else if (param.seriesName === '停机时间') {
            result += `${param.marker} ${param.seriesName}: ${param.value} 分钟<br>`;
          }
        });
        return result;
      },
    },
    legend: {
      data: ["停机时间","停机次数"],
      orient: "horizontal",
      left: "left",
      top: "top",
      itemGap: 10,
    },
    xAxis: {
      type: "category",
      data: series_data1.value,
      axisLabel: {
        rotate: 30,
      },
    },
    yAxis: [
      {
        type: "value",
        name: "停机时间 (分钟)",
        splitLine: { show: false },
      },
      {
        type: "value",
        name: "故障次数",
        splitLine: { show: false },
      },
    ],
    series: [
      {
        name: "停机次数",
        type: "line",
        data: faultCountData,
        yAxisIndex: 1,
        color: "#3398DB",
        label: {
          show: true,
          position: "top",
          formatter: function (param) {
            return param.value;
          },
        },
      },
      {
        name: "停机时间",
        type: "bar",
        data: stopDurationData,
        yAxisIndex: 0,
        color: "#59c4e6",
        label: {
          show: true,
          position: "top",
          formatter: function (param) {
            return param.value;
          },
        },
      },
    ],
  };

  myChart.setOption(option);

  myChart.on("click", (params) => {
    if (params.componentType === "series" && params.name) {
      const selectedHourRange = params.name;

      try {
        const [datePart, timePart] = selectedHourRange.split(" ");
        const [startTime, endTime] = timePart.split("-");

        const [month, day] = datePart.split("-").map(num => parseInt(num, 10));
        const [startHour, startMinute] = startTime.split(":").map(num => parseInt(num, 10));
        const [endHour, endMinute] = endTime.split(":").map(num => parseInt(num, 10));

        const year = new Date().getFullYear();

        const startDate = new Date(year, month - 1, day, startHour, startMinute, 0);
        const endDate = new Date(year, month - 1, day, endHour, endMinute, 0);

        const startFormatted = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")} ${String(startHour).padStart(2, "0")}:${String(startMinute).padStart(2, "0")}:00`;
        const endFormatted = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")} ${String(endHour).padStart(2, "0")}:${String(endMinute).padStart(2, "0")}:00`;

        console.log(`开始时间: ${startFormatted}, 结束时间: ${endFormatted}`);
        console.log("point_id", point_id);
        useShowDataTableData2(point_id, startFormatted, endFormatted);
      } catch (error) {
        console.error("Error parsing hour range:", error);
      }
    } else {
      console.error("No valid series or name:", params);
    }
  });
};

const initChart3 = async () => {
  if (chart3.value == null) {
    return;
  }

  echarts.dispose(chart3.value);
  const myChart = echarts.init(chart3.value);

  const sortedData = series_data3.value.map(item => ({
    name: item.name,
    value: parseFloat(item.value).toFixed(2),
    stopCount: item.stopCount,
  }));
  console.log('series_data3.value',series_data3.value)
  let colors;
  if (chartType.value === 'data') {
    colors = sortedData.map((item, index) => index < 3 ? "#D84A62" : "#59c4e6");
  } else if (chartType.value === 'assetnum') {
    colors = sortedData.map(() => "#59c4e6");
  }

  let option = {
    title: {
      text: `${value3.value}停机时间总计`,
      left: "center",
      textStyle: {
        color: "black",
      },
      subtextStyle: {
        fontWeight: "bold",
      },
    },
    tooltip: {
      trigger: "axis",
      formatter: function (params) {
        let result = params[0].name + "<br/>";
        params.forEach(param => {
          if (param.seriesName === '停机时间') {
            const value = parseFloat(param.value).toFixed(2);
            result += `${param.seriesName}: ${value} 分钟<br/>`;
          } else if (param.seriesName === '停机次数') {
            result += `${param.seriesName}: ${param.value}<br/>`;
          }
        });
        return result;
      },
    },
    legend: {
      data: ["停机时间", "停机次数"],
      orient: "horizontal",
      left: "left",
      top: "top",
      itemGap: 10,
    },
    xAxis: {
      type: "category",
      data: sortedData.map(item => item.name),
      axisLabel: {
        rotate: 45,
      },
    },
    yAxis: [
      {
        type: 'value',
        name: '停机时间 (分钟)',
        splitLine: { show: false },
      },
      {
        type: 'value',
        name: '故障次数',
        splitLine: { show: false },
      },
    ],
    series: [
      {
        name: '停机时间',
        data: sortedData.map((item, index) => ({
          name: item.name,
          value: item.value,
          itemStyle: {
            color: colors[index]
          }
        })),
        type: "bar",
        label: {
          show: true,
          position: 'top',
          formatter: function (param) {
            const value = parseFloat(param.value).toFixed(2);
            return value;
          },
        },
      },
      {
        name: '停机次数',
        data: sortedData.map(item => item.stopCount),
        type: "line",
        yAxisIndex: 1,
        color: "#3398DB",
        label: {
          show: false,
          position: 'top',
        },
      },
    ],
  };

  myChart.on('click', (params) => {
    console.log('Clicked:', params);
    const point_id = params.name;
    useShowDataInHtmlForTable(point_id);
  });

  myChart.setOption(option);
};

onMounted(() => {
  value2.value = [new Date(new Date().setHours(0, 0, 0, 0)), new Date()];
  use_show_data_in_html2();
  updatePagedData();
  useShowDataInHtmlForTable('CBM1OP10A')
});

</script>